package com.bt7274.interceptor;

import com.bt7274.annotation.RequireLogin;
import com.bt7274.enums.ResultCodeEnum;
import com.bt7274.exception.BusinessException;
import com.bt7274.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * Authorization Interceptor - validates JWT tokens and user permissions
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // Check if method or class has RequireLogin annotation
        RequireLogin requireLogin = method.getAnnotation(RequireLogin.class);
        if (requireLogin == null) {
            requireLogin = handlerMethod.getBeanType().getAnnotation(RequireLogin.class);
        }

        // If no RequireLogin annotation, skip validation
        if (requireLogin == null) {
            return true;
        }

        // 从请求中获取token
        String token = JwtUtil.getTokenFromRequest(request);
        if (token == null) {
            throw new BusinessException(ResultCodeEnum.UNAUTHORIZED);
        }

        try {
            // Parse and validate token
            Claims claims = (Claims) JwtUtil.getClaimsFromToken(token);

            // Check token expiration
            if (!JwtUtil.validateExpiration(claims)) {
                throw new BusinessException(ResultCodeEnum.TOKEN_EXPIRED);
            }

            // Check role if required
            if (requireLogin.checkRole()) {
                Integer userRole = JwtUtil.getRoleFromClaims(claims);
                if (userRole < requireLogin.role()) {
                    throw new BusinessException(ResultCodeEnum.FORBIDDEN);
                }
            }

            // 设置 userId 到请求属性中
            String userId = JwtUtil.getUserIdFromClaims(claims);
            request.setAttribute("userId", userId.toString());

            // Token is valid, continue
            return true;
        } catch (ExpiredJwtException e) {
            throw new BusinessException(ResultCodeEnum.TOKEN_EXPIRED);
        } catch (JwtException e) {
            throw new BusinessException(ResultCodeEnum.INVALID_TOKEN);
        }
    }
}